;    DateTime.s - Rotinas p/ pegar data do sistema
;    Copyright (C) 2005 - 2007 Gilmar Santos Jr (gilmarjr@dcc.ufba.br)
;
;    This program is free software; you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation; either version 2 of the License, or
;    (at your option) any later version.
;
;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.
;
;    You should have received a copy of the GNU General Public License along
;    with this program; if not, write to the Free Software Foundation, Inc.,
;    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

%include "macros.i"

extern	_IntToAsc
extern	_AscToInt

global	_GetDateTimeBin
global	_GetDateTimeAsc

section .data

tabmes	dd	60 * 60 * 24 * 31,
		dd	60 * 60 * 24 * 28,
		dd	60 * 60 * 24 * 31,
		dd	60 * 60 * 24 * 30,
		dd	60 * 60 * 24 * 31,
		dd	60 * 60 * 24 * 30,
		dd	60 * 60 * 24 * 31,
		dd	60 * 60 * 24 * 31,
		dd	60 * 60 * 24 * 30,
		dd	60 * 60 * 24 * 31,
		dd	60 * 60 * 24 * 30,
		dd	60 * 60 * 24 * 31

section .bss

ano			resd	1
mes			resd	1
dia			resd	1
hora		resd	1
minuto		resd	1
segundo		resd	1

section .text

; int bissexto(int ano);
_bissexto:

; +---------------------------------------------------------------------+
; | Chamada:	xcall	_bissexto,ano                                   |
; |                                                                     |
; |		ano   resw 1                                                    |
; |                                                                     |
; | Retorno:                                                            |
; |                                                                     |
; |     eax == 0 --> Nao eh bissexto                                    |
; |     eax == 1 --> Eh bissexto                                        |
; +---------------------------------------------------------------------+
	push	ebp
	mov		ebp,esp
	mov		eax,[ebp +  8]
	push	eax
	mov		ebx,4
	xor		edx,edx
	div		ebx
	cmp		edx,0
	jne		.NotBissexto
	pop		eax
	mov		ebx,100
	div		ebx
	cmp		ebx,0
	jne		.Bissesxto
	mov		ebx,4
	div		ebx
	cmp		edx,0
	jne		.NotBissexto
.Bissesxto:
	mov		eax,1
	jmp		.Fim
.NotBissexto:
	xor		eax,eax

.Fim:
	leave
	ret

; void GetDateTime(int *ano, int *mes, int *dia, int *hora, int *min, int *seg [, int *time]);
_GetDateTimeBin:
	push	ebp
	mov		ebp,esp
	mov		eax,13				; sys_time <= retorna a quantidade de segundos desde 01/01/1970 00:00 UTC
	mov		ebx,[ebp + 32]
	int		0x80
	sub		eax, 60 * 60 * 3	; Retirando 3 horas para transformar o fuzo de UTC para BRT

.PreparaAno:
	mov		ecx,1970
.LoopAno:
	mov		ebx, 60 * 60 * 24 * 365
	push	eax			; Quantidade de segundos desde a epoca
	xcall	_bissexto,ecx
	cmp		eax,0
	je		.IteraAno
	add		ebx, 60 * 60 * 24
.IteraAno:
	pop		eax
	cmp		eax,ebx
	jb		.FimAno
	sub		eax,ebx
	inc		ecx
	jmp		.LoopAno
.FimAno:
	mov		edi,[ebp +  8]
	mov		dword [edi],ecx

.PreparaMes:
	mov		ebx,ecx
	xor		ecx,ecx
.LoopMes:
	cmp		ecx,1
	jne		.IteraMes
	push	eax
	xcall	_bissexto,ebx
	mov		edx,eax
	pop		eax
	cmp		edx,0
	je		.IteraMes
	cmp		eax, 60 * 60 * 24 * 29
	jb		.FimMes
	sub		eax, 60 * 60 * 24 * 29
	inc		ecx
	jmp		.LoopMes
.IteraMes:
	cmp		eax,dword [tabmes + ecx * 4]
	jb		.FimMes
 	sub		eax,dword [tabmes + ecx * 4]
	inc		ecx
	jmp		.LoopMes
.FimMes:
	inc		ecx			; ecx => Mes (1 => Jan, 2 => Fev ...)
	mov		edi,[ebp + 12]
	mov		dword [edi],ecx

.PegaDia:
	xor		edx,edx
	mov		ebx, 60 * 60 * 24
	div		ebx
	inc		eax
	mov		edi,[ebp + 16]
	mov		dword [edi],eax
	mov		eax,edx

.PegaHora:
	xor		edx,edx
	mov		ebx, 60 * 60
	div		ebx
	mov		edi,[ebp + 20]
	mov		dword [edi],eax
	mov		eax,edx

.PegaMinuto:
	xor		edx,edx
	mov		ebx, 60
	div		ebx
	mov		edi,[ebp + 24]
	mov		dword [edi],eax
	mov		eax,edx

.PegaSegundo:
	mov		ebx,[ebp + 28]
	mov		dword [ebx], eax
	xor		eax,eax
	
	leave
	ret

; void GetDateTimeAsc([char *data][, char *hora]);
_GetDateTimeAsc:
	push	ebp
	mov		ebp,esp
	xcall	_GetDateTimeBin,ano,mes,dia,hora,minuto,segundo

.CarregaData:
	mov		edi,[ebp +  8]
	cmp		edi,0
	jne		.PreencheData
	jmp		.CarregaHora
.PreencheData:
	mov		byte [edi],'0'
	mov		byte [edi + 2],'/'
	mov		byte [edi + 3],'0'
	mov		byte [edi + 5],'/'
	xcall	_IntToAsc,dword [dia],edi,2
	add		edi,3
	xcall	_IntToAsc,dword [mes],edi,2
	add		edi,3
	xcall	_IntToAsc,dword [ano],edi,4

.CarregaHora:
	mov		edi,[ebp + 12]
	cmp		edi,0
	jne		.PreencheHora
	jmp		.Fim
.PreencheHora:
	mov		byte [edi],'0'
	mov		byte [edi + 2],':'
	mov		byte [edi + 3],'0'
	mov		byte [edi + 5],':'
	mov		byte [edi + 6],'0'
	xcall	_IntToAsc,dword [hora],edi,2
	add		edi,3
	xcall	_IntToAsc,dword [minuto],edi,2
	add		edi,3
	xcall	_IntToAsc,dword [segundo],edi,2

.Fim:
	leave
	ret

